package org.swift.mashup.engine.model;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.script.Bindings;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

import org.swift.mashup.engine.jsr223.ScriptCache;
import org.swift.mashup.engine.jsr223.ScriptExecutor;

public class JSR223ScriptActivity implements Activity {

	protected static final String FROM_PARAMETER_NAME = "source";

	protected final String language;
	protected final String scriptcode;
	
	public JSR223ScriptActivity(String language, String scriptcode) {
		this.language = language;
		this.scriptcode = scriptcode;
		ScriptCache.getInstance().clear(language);
	}

	public ActivityResultComponent doActivity(
			ActivityContext context,
			Map<String, ? extends Object> parameters) 
		throws ActivityException {

		try {
			Bindings bindings = new SimpleBindings();
			
			if (context != null && context.getSize() > 0) {
				bindings.put( FROM_PARAMETER_NAME, new String(context.getBytes()) );
			}
			
			if ( parameters != null ) {
				for ( Map.Entry<String, ? extends Object> parameter : parameters.entrySet() ) {
					bindings.put( parameter.getKey(), parameter.getValue() );
				}
			}
			
			Object returnobject = new ScriptExecutor().execute(this.language, this.scriptcode, bindings);
			return createActivityResult(returnobject);
		}
		catch (IOException e) {
			throw new ActivityException("IOException: " + e.getMessage(),e);
		}		
		catch (ScriptException e) {
			throw new ActivityException("ScriptException: " + e.getMessage(),e);
		}		
	}
	
	@SuppressWarnings("unchecked")
	protected ActivityResultComponent createActivityResult(Object resultObject) throws ActivityException {
		ActivityResultComponent arc = null;
		
		if ( resultObject instanceof Collection ) {
			arc = new ActivityResultGroup();
			
			for ( Iterator i = ((Collection)resultObject).iterator(); i.hasNext(); ) {
				arc.add( new ActivityResultItem(i.next()) );
			}
		}
		else {
			arc = new ActivityResultItem(resultObject);
		}
		
		return arc;
	}
}
